from Agent.Agent import Agent
from llm import *
from SeqTools.ActionDetectorB import *

prompt = '''

以下是小船航行状态规则的说明：

1. 停泊状态：
   - 停泊及船舶靠港，系泊在码头。
   - 供电：由柴油发电机组供电或岸上供电（后者较少）。
   - 推进：推进器和舵桨基本不工作，但可能短暂使用推进器进行船位调整或加油加淡水操作。靠港和离港时一般需要艏侧推进器配合。
   - 甲板机械：停泊时不会作业，但可能进行设备调试或测试。

2. 航渡状态：
   - 指一般的航行状态，通常在港口码头与作业地点之间。
   - 供电：只能通过柴油发电机供电。
   - 推进：主推进器必须运行，通常以相对稳定的转速运行，速度较高。
   - 甲板机械：航渡时不会作业，但可能进行设备调试或测试。

3. 动力定位状态：
   - 伴随作业，将船稳定在作业点附近以便进行科考作业。
   - 供电：只能通过柴油发电机供电。
   - 推进：一般需要主推进器、艏侧推和可伸缩推进器配合，可伸缩推进器在海况较差时会配合运行。
   - 甲板机械：一般都会作业，所以有甲板机械运行。

4. 伴航状态：
   - 主要发生在船舶等待潜器回收的过程中，如深海作业A布放和回收过程之间。
   - 供电：只能通过柴油发电机供电。
   - 推进：一般需要主推进器运行，速度较低，艏侧推和可伸缩推不一定需要运行。
   - 甲板机械：伴航时不会作业，但可能进行设备调试或测试。

一般情况：停泊状态结束后进入航渡状态来到作业点，开启动力定位状态进行作业，然后开启伴航状态跟踪作业机械，最后开启航渡状态回到停泊点休息。

判断规则:

`动力定位状态`
艏推工作开始到艏推工作结束，并且中间有作业工作，一般持续时间较长的为`动力定位状态`，其余的只是调转方向，不算`动力定位状态`。
开始时间为艏推工作开始`P3_33`>0的时间点，结束为P3_33 列变为0的时间点。

艏推工作结束可能进入`停泊状态`,`航渡状态`,`伴航状态`，这三个状态的开始时间为艏推工作结束的时间，即 P3_33 列为0
结束后一段时间发生一号柴油发电机组有功功率（P1_66）测量为0时，为停泊状态
结束一段事件后进入全速前进状态为`航渡状态`
结束时如果一号柴油发电机组有功功率测量为200-500，并且长时间没有新的特征行，为伴航状态

这三个状态结束的时间分别为：

`停泊状态`结束：下一次艏推开始工作，且一号柴油发电机组有功功率（P1_66）测量长期大于0，按照艏推开始工作时间计算
`航渡状态`结束：一号柴油发电机组有功功率（P1_66）测量显著下降,到某个稳定值的时候，取下降的时间点。
`伴航状态`结束：下一次艏推开始工作，工作结束后进入其他状态，如动力定位状态，航渡状态，按照艏推开始工作时间计算

特点：停泊状态一般是作业结束休息，时间较长，航渡状态一般为休息结束赶去作业地点，持续时间较长，伴航状态一般是工作结束，跟随探测器，发生在工作结束后。
动力定位状态结束后的航行，一定是伴航状态。
这三种航行状态，持续时间必须大于1小时。

我会给你一个表格，并且标注了一些特征点，你会根据上述流程，分析对应的动作，然后回答用户的问题。
其中 表格有 五列 
第一列：Ajia-3_v  表示是否有甲板作业
第二列：P3_33表示艏推功率，有功率时启动，同时开启动力定位。
第三列：P1_66表示柴油发电机功率，与航行速度线性相关
csvTime表示时间，特征为硬规则匹配的特征，非实际情况，你会基于此列进行分析。

总体来说以上操作有一定逻辑性，你需要按照逻辑分析动作。


按照以下格式分析和输出：
--格式--
<think>在这里进行逻辑分析</think>
开始时间 yyyy-mm-dd hh:mm:ss 结束时间:yyyy-mm-dd hh:mm:ss -> `状态名称1`
开始时间 yyyy-mm-dd hh:mm:ss 结束时间:yyyy-mm-dd hh:mm:ss  ->`状态名称2`
开始时间 yyyy-mm-dd hh:mm:ss 结束时间:yyyy-mm-dd hh:mm:ss -> `状态名称1` # 相同状态不同时间分条列出
---
以下是一个示例：
表格：
| Ajia-3_v   |   P3_33 |   P1_66 | csvTime             | 特征                                                                        |
|:-----------|--------:|--------:|:--------------------|:----------------------------------------------------------------------------|
| error      |       0 |     290 | 2024-05-19 06:46:00 |                                                                             |
| error      |       0 |     263 | 2024-05-19 06:47:00 |                                                                             |
| error      |     585 |     393 | 2024-05-19 06:48:00 | `艏推开始工作`特征行                                                        |
| 0          |     581 |     346 | 2024-05-19 07:31:00 | `甲板工作启动`特征行                                                        |
| 99.208     |     566 |     456 | 2024-05-19 08:32:00 |                                                                             |
| 55.5609    |       0 |     283 | 2024-05-19 08:33:00 | `艏推工作结束`特征行                                                        |
| 55.8183    |       0 |     266 | 2024-05-19 08:34:00 |                                                                             |
| 0          |       0 |     261 | 2024-05-19 15:38:00 |                                                                             |
| 0          |       0 |     277 | 2024-05-19 15:39:00 | `甲板工作结束`特征行                                                        |
| error      |       0 |     277 | 2024-05-19 15:40:00 |                                                                             |
| error      |       0 |     265 | 2024-05-19 15:41:00 |                                                                             |
| 0          |       0 |     263 | 2024-05-19 15:42:00 | `甲板工作启动`特征行                                                        |
| 0          |       0 |     283 | 2024-05-19 15:44:00 |                                                                             |
| 0          |       0 |     172 | 2024-05-19 16:47:00 |                                                                             |
| 0          |       0 |     167 | 2024-05-19 16:48:00 | `艏推开始工作`特征行                                                        |
| 0          |     766 |     283 | 2024-05-19 16:49:00 | `艏推开始工作`特征行                                                        |
| 0          |     739 |     250 | 2024-05-19 16:50:00 |                                                                             |
| 55.4785    |     756 |     305 | 2024-05-19 17:09:00 |                                                                             |
| 55.6246    |       0 |     217 | 2024-05-19 17:10:00 | `艏推工作结束`特征行                                                        |
| 111.355    |       0 |     252 | 2024-05-19 17:11:00 |                                                                             |
| 0          |       0 |     296 | 2024-05-19 17:23:00 |                                                                             |
| 0          |       0 |     305 | 2024-05-19 17:24:00 | `甲板工作结束`特征行                                                        |
| error      |       0 |     266 | 2024-05-19 17:25:00 |                                                                             |
| error      |       0 |     325 | 2024-05-19 23:53:00 |                                                                             |
| error      |       0 |     323 | 2024-05-19 23:54:00 | 全速前进特征                                                                |
| error      |       0 |     850 | 2024-05-19 23:55:00 | 全速前进特征                                                                |
| error      |       0 |     831 | 2024-05-19 23:56:00 |                                                                             |
| error      |       0 |     330 | 2024-05-20 05:41:00 |                                                                             |
| error      |     552 |     393 | 2024-05-20 05:42:00 | `艏推开始工作`特征行                                                        |
| error      |     571 |     272 | 2024-05-20 05:43:00 |                                                                             |
<think>
2024-05-19 06:48:00 艏推开始工作 随后进行甲板作业，可以推测其状态为：`动力定位状态`，
随后 2024-05-19 08:33:00 艏推工作结束，随后甲板作业结束，符合逻辑，此时 `动力定位状态` 结束。
此时应该已经下放探测器。
直到2024-05-19 16:48:00 又开始艏推开始工作，根据深海作业流程分析，作业结束应该跟随探测器进行伴航
2024-05-19 08:33:00- 2024-05-19 16:48:00为`伴航状态`。
2024-05-19 17:10:00 艏推工作结束特征行最后进行全速航行，但是间隔时间比较长，应该是慢速航行，也为`航渡状态`开始，此时应该需要停泊休息。
</think>
开始时间 2024-05-19 06:48:00 结束时间:2024-05-19 08:33:00 -> `动力定位状态`
开始时间 2024-05-19 08:33:00 结束时间:2024-05-19 16:48:00 -> `伴航状态`
开始时间 2024-05-19 17:10:00 结束时间:未知 -> `航渡状态`

以后的分析按照示例格式，即按照时间，自上而下分析，如果用户提问，大概率是有答案的，尽可能按照有答案来分析。
'''

time_prompt = '''
请提取以下问题中的时间范围，按照天来计算，并且前后各增加一天。

按照
```json
[
{"start_time":"yyyy-mm-dd hh:mm:ss","end_time":"yyyy-mm-dd hh:mm:ss"},
...
]
```
的格式输出。
示例:
user:2024/8/24-26之间，发生了哪些航行状态,9月10号呢？
assistant:```json
[
  {"start_time":"2024-08-23 00:00:00","end_time":"2024-08-27 23:59:59"},
  {"start_time":"2024-09-09 00:00:00","end_time":"2024-09-11 23:59:59"}
]
```
如果时间跨度超过5天，请拆分输出，最多五天：
user:2024/8/20-29之间，发生了哪些航行状态？
assistant:```json
[
  {"start_time":"2024-08-19 00:00:00","end_time":"2024-08-24 23:59:59"},
  {"start_time":"2024-08-24 00:00:00","end_time":"2024-08-29 23:59:59"}
]
```
'''


class NavigateAgent(Agent):

    def __init__(self, name,
                 description,
                 system_prompt,
                 agent_type,
                 llm_engine,
                 agents=None,
                 rag=None, sample=None):
        super().__init__(name,
                         description,
                         system_prompt,
                         agent_type,
                         llm_engine,
                         agents,
                         rag)

        self.sample = sample

    def _get_data(self, start_time, end_time):
        data = {"数据": {
            "Ajia_plc_1": ["Ajia-3_v", "Ajia-5_v"],
            "device_1_2_meter_102": ["1-2-6_v"],
            "Port3_ksbg_9": ["P3_18", "P3_33"],
            "Port3_ksbg_10": ['P3_22'],
            "Port1_ksbg_3": ["P1_66",'P1_75'],
            'Port2_ksbg_2':['P2_51'],
            "Port2_ksbg_3": ['P2_60']
        }, "时间": {
            "开始": start_time,
            "结束": end_time
        }}

        df = process_data(data)
        detector = ActionDetector(df)
        df2 = detector.preprocess(detect_list)
        df2 = df2[['Ajia-3_v', 'P3_33', 'P1_66', 'csvTime', '特征']]
        res = df2.to_markdown(index=False)
        if len(enc.encode(res))<10000:
            return res

        df2 = df2[df2['特征'].apply(lambda x: len(str(x))>5)]
        res = df2.to_markdown(index=False)
        if len(enc.encode(res))<10000:
            return res
        df2 = df2[df2['特征'].apply(lambda x: len(str(x))>5)]
        df2 = df2[['csvTime','特征']]
        res = df2.to_markdown(index=False)
        # if len(enc.encode(res))<10000:
        return res

    def get_data(self,start_time, end_time):
        return re.sub('       +','       ',self._get_data(start_time, end_time))

    def del_row(self,content:str):
        content_list =  content.split('\n')
        content_list = [i for i in content_list if not re.search('\| +\|',i)]
        if len(content_list)>50:
            content_list = content_list[:20]+content_list[-20:]
        return '\n'.join(content_list)

    def build_prompt(self, question):
        self.messages =[{"role": "system", "content": self.system_prompt},
                         ]
        sample_msg = self.sample.get_sample(question, 1)
        for i in sample_msg[0]:
            if ' 的数据如下：' in i['content']:
                i['content'] = self.del_row(i['content'])
        self.messages.extend(sample_msg[0])

    def run(self, question):
        time_range = self.llm_engine([{"role": "system", "content": time_prompt},
                                      {"role": "user", "content": question}])
        time_range = super_eval(time_range)
        self.messages = [{"role": "system", "content": self.system_prompt},
                         ]

        sea_log = ''

        for i in time_range:
            processed_data = self.get_data(i["start_time"], i["end_time"])
            self.messages.append({"role": "user",
                                  "content": f'''
当前问题：{question}
其中:{i["start_time"]} - {i["end_time"]} 的数据如下：
---
{processed_data}
---
请基于日志思考分析题目,只回答日志可以覆盖到的答案，重新思考。
'''})
            sea_log += self.llm_engine(self.messages)
        with open('./sample/navigate3.jsonl', 'a', encoding='utf-8') as fw:
            fw.write(
                json.dumps({"question": question, "messages": self.messages[1:]}, ensure_ascii=False)
            )
            fw.write('\n')
        return re.sub('<think>.*?</think>','',sea_log,re.DOTALL)


from get_sample import get_navigate_sample
NavigateAgentConfig = {"name": 'xxx',
                       "description": 'xxx',
                       'system_prompt': prompt,
                       'agent_type': 'plan-action',
                       'llm_engine': llm,
                       'sample':get_navigate_sample(),
                       'agents': None}

navigate_agent = NavigateAgent(**NavigateAgentConfig)
